/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package so.n_3.musicbox.model;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Date;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.io.FileUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 *
 * @author oasynnoum
 */
public class Playlist {
    
    private String id;
    
    private Vector<Music> musics;
    
    private String name;
    
    private String url;
    
    public Playlist() {
        this.musics = new Vector<Music>();
    }
    
    public Vector<Music> getMusics() {
        return this.musics;
    }
    
    public void setUrl(String url) {
        this.url = url;
    }
    
    public String getUrl() {
        return this.url;
    }
    
    public Music getMusic(int order) {
        return this.musics.get(order);
    }
    
    public void addMusic(Music music) {
        this.musics.add(music);
    }
    
    public void setMusics(Vector<Music> musics) {
        this.musics = musics;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getId() {
        return this.id;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getName() {
        return this.name;
    }
    
    public boolean remove(boolean isRemoveDirectory) {
        boolean result = false;
        
        try {
            Document document = MusicBox.getInstance().getPlaylistXmlDocument();
            Element musicboxElem = (Element) document.getElementsByTagName("musicbox").item(0);
            Element playlistElem = null;
            NodeList playlistElems = document.getElementsByTagName("playlist");
            for (int i = 0; i < playlistElems.getLength(); i++) {
                Element _playlistElem = (Element)playlistElems.item(i);
                if (_playlistElem.getAttribute("id").equals(this.id)) {
                    playlistElem = _playlistElem;
                    break;
                }
            }
            musicboxElem.removeChild(playlistElem);
            
            if (isRemoveDirectory) {
                try {
                    FileUtils.deleteDirectory(new File(this.url));
                    result = true;
                } catch (Exception ex) {
                    Logger.getLogger(Playlist.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else {
                result = true;
            }
            
            result = result && MusicBox.getInstance().savePlaylistXmlDocument(document);
        } catch (Exception ex) {
            Logger.getLogger(Playlist.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return result;
    }
    
    public boolean sync() {
        boolean result = false;
        String playlistXmlPath = MusicBox.getPlaylistXmlPath();
        File playlistXml = new File(playlistXmlPath);
        try {
            Document document = MusicBox.getInstance().getPlaylistXmlDocument();
            Element playlistElem = null;
            NodeList playlistElems = document.getElementsByTagName("playlist");
            for (int i = 0; i < playlistElems.getLength(); i++) {
                Element _playlistElem = (Element)playlistElems.item(i);
                if (_playlistElem.getAttribute("id").equals(this.id)) {
                    playlistElem = _playlistElem;
                    break;
                }
            }
            NodeList children = playlistElem.getChildNodes();
            for (int i = children.getLength() - 1; i >= 0; i--) {
                Node child = children.item(0);
                playlistElem.removeChild(child);
            }
            
            File sourceDirectory = new File(this.url);
            File[] mp3Files = sourceDirectory.listFiles(MusicBox.getMP3FileFilter());
            
            for (int i = 0; i < mp3Files.length; i++) {
                File mp3File = mp3Files[i];
                Element musicElem = document.createElement("music");
                musicElem.setAttribute("url", mp3File.getAbsolutePath());
                musicElem.setAttribute("order", Integer.toString(i));
                playlistElem.appendChild(musicElem);
            }
            
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.transform(new DOMSource(document), new StreamResult(playlistXml));
            MusicBox.init(MusicBox.getPlaylistXmlPath());
            result = true;
        } catch (TransformerConfigurationException ex) {
            Logger.getLogger(Playlist.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TransformerException ex) {
            Logger.getLogger(Playlist.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return result;
    }
    
    /**
     * this method only remove music file. will not manipulate playlist xml file.
     * you must call Playlist#sync() method when this method returned if you specified false as doSync.
     * 
     * @param order
     * @param doSync
     * @return 
     */
    public boolean removeMusic(int order, boolean doSync) {
        boolean result = false;
        
        Music music = this.getMusic(order);
        File musicFile = new File(music.getUrl());
        result = musicFile.delete();
        
        if (doSync) {
            result = result && this.sync();
        }
        return result;
    }
    
    public static String generateId() {
        return "playlist-" + Long.toString(System.currentTimeMillis());
    }
}
